home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 11
/
CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso
/
cucd
/
graphics
/
mpimage
/
si
/
scalempi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-02-16
|
41KB
|
2,042 lines
// MPImage - Amiga Image Conversion
// Copyright (C) © 1996 Mark John Paddock
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mark@topic.demon.co.uk
// mpaddock@cix.compulink.co.uk
#include "mpimage.h"
BOOL __asm __saveds RescaleMPImage(register __a0 struct MPImage *MPi,register __d0 UWORD x,
register __d1 UWORD y);
static void RescaleXY(UBYTE *in,UWORD w,UWORD h,UBYTE *out,UWORD x,UWORD y,UBYTE *temp);
static void SmoothX(UBYTE *in,UBYTE *out,UWORD w,UWORD x,UWORD y);
static void SmoothY(UBYTE *in,UBYTE *out,UWORD h,UWORD x,UWORD y);
static void SmoothXY(UBYTE *in,UBYTE *out,UWORD w,UWORD h,UWORD x,UWORD y);
static void RescaleXYRGB(UBYTE *inr,UBYTE *ing,UBYTE *inb,UWORD w,UWORD h,UBYTE *outr,UBYTE *outg,UBYTE *outb,
UWORD x,UWORD y,UBYTE *tr,UBYTE *tg,UBYTE *tb);
/****** MPImage.library/RescaleMPImage **************************************
*
* NAME
* RescaleMPImage -- Scales an image created by LoadMPImage() (V3)
*
* SYNOPSIS
* error = RescaleMPImage(MPi, x, y)
* D0 A0 D0 D1
*
* BOOL RescaleMPImage(struct MPImage *, UWORD, UWORD);
*
* FUNCTION
* Scales an Image loaded by LoadMPImage() to new width and height.
*
* INPUTS
* MPi - Image loaded by LoadMPImage
* x - New width of image
* y - New height of image
*
* RESULT
* error - 1 for success, 0 for failure.
* Use MPImageErrorMessage() to get error.
*
* EXAMPLE
*
* NOTES
* Rescaling of bitmaps is done using BitMapScale().
* Other rescaling is done using custom code with smoothing.
*
* If this function fails then the MPImage is no longer usable and
* FreeMPImage() should be called to free it.
*
* Version 4.3 is faster for RGB.
*
* BUGS
* Bitmaps may not scale smoothly.
* The rescaling of EGS images is not efficent.
*
* SEE ALSO
* LoadMPImage(),MPImageErrorMessage(),FreeMPImage(),
* graphics.library/BitMapScale().
*
*****************************************************************************
*
*/
BOOL __asm __saveds
RescaleMPImage(register __a0 struct MPImage *MPi,register __d0 UWORD x,
register __d1 UWORD y) {
UBYTE *msg;
if (!SetupScreen()) {
OpenProgressWindow();
}
if (MPi->BitMap) {
// Normal BitMap
struct BitMap *bitmap;
if (!(bitmap = AllocBitMap(x,y, MPi->BitMap->Depth,BMF_DISPLAYABLE,MPi->BitMap))) {
msg = GetMg(MSG_ERR_ALLOCBIT);
}
else {
struct BitScaleArgs BitScaleArgs;
AddMessageNo(MSG_SCALE);
BitScaleArgs.bsa_SrcX = 0;
BitScaleArgs.bsa_SrcY = 0;
BitScaleArgs.bsa_SrcWidth = MPi->Width;
BitScaleArgs.bsa_SrcHeight = MPi->Height;
BitScaleArgs.bsa_DestX = 0;
BitScaleArgs.bsa_DestY = 0;
BitScaleArgs.bsa_DestWidth = x;
BitScaleArgs.bsa_DestHeight = y;
BitScaleArgs.bsa_XSrcFactor = MPi->Width;
BitScaleArgs.bsa_XDestFactor = x;
BitScaleArgs.bsa_YSrcFactor = MPi->Height;
BitScaleArgs.bsa_YDestFactor = y;
BitScaleArgs.bsa_SrcBitMap = MPi->BitMap;
BitScaleArgs.bsa_DestBitMap = bitmap;
BitScaleArgs.bsa_Flags = 0;
BitMapScale(&BitScaleArgs);
if (MPi->Object) { // Dispose object (frees bit map as well...)
DisposeDTObject(MPi->Object);
MPi->Object = NULL;
}
else {
FreeBitMap(MPi->BitMap);
}
MPi->BitMap = bitmap;
MPi->Width = x;
MPi->Height = y;
CloseProgressWindow();
CloseDownScreen();
return TRUE;
}
}
else {
if (MPi->EGS_BitMap) {
// EGS BitMap
UBYTE *red,*green=NULL,*blue=NULL,*plane;
UBYTE *r,*g=NULL,*b=NULL,*t=NULL,*t1,*t2;
UBYTE *rr,*gg,*bb;
UWORD i,j;
AddMessageNo(MSG_SCALEE);
if (!(EGSBase = OpenLibrary((char *)"egs.library",0))) {
msg = GetMg(MSG_ERR_EGSL);
strcpy(ErrorMessage,msg);
CloseProgressWindow();
CloseDownScreen();
return FALSE;
}
if ((red = AllocVec((int)MPi->Width*MPi->Height,0)) &&
(green = AllocVec((int)MPi->Width*MPi->Height,0)) &&
(blue = AllocVec((int)MPi->Width*MPi->Height,0))) {
plane = ((struct E_EBitMapFull *)(MPi->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
rr = red;
gg = green;
bb = blue;
AddMessageNo(MSG_E2C);
SetMax(MPi->Height);
for (i = 0; i<MPi->Height; i++) {
SetCur(i);
for (j = 0; j<MPi->Width; j++) {
*rr++ = *plane++;
*gg++ = *plane++;
*bb++ = *plane++;
plane++;
}
plane += (MPi->EGS_BitMap->BytesPerRow - (4*MPi->Width));
}
E_DisposeBitMap(MPi->EGS_BitMap);
MPi->EGS_BitMap = NULL;
if ((r = AllocVec((int)x*y,0)) &&
(g = AllocVec((int)x*y,0)) &&
(b = AllocVec((int)x*y,0)) &&
(t = AllocVec((int)x*y,0))) {
AddMessageNo(MSG_SCALER);
if ((t1 = AllocVec((int)x*y,0)) &&
(t2 = AllocVec((int)x*y,0))) {
RescaleXYRGB(red,green,blue,MPi->Width,MPi->Height,r,g,b,x,y,t,t1,t2);
FreeVec(t1);
FreeVec(t2);
}
else {
if (t1) {
FreeVec(t1);
}
RescaleXY(red,MPi->Width,MPi->Height,r,x,y,t);
RescaleXY(green,MPi->Width,MPi->Height,g,x,y,t);
RescaleXY(blue,MPi->Width,MPi->Height,b,x,y,t);
}
FreeVec(red);
red = NULL;
FreeVec(green);
green = NULL;
FreeVec(blue);
blue = NULL;
if (MPi->EGS_BitMap = E_AllocBitMap(x,y,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
plane = ((struct E_EBitMapFull *)(MPi->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
rr = r;
gg = g;
bb = b;
AddMessageNo(MSG_2E);
SetMax(y);
for (i = 0; i<y; i++) {
SetCur(i);
for (j = 0; j<x; j++) {
*plane++ = *rr++;
*plane++ = *gg++;
*plane++ = *bb++;
plane++;
}
plane += (MPi->EGS_BitMap->BytesPerRow - (4*x));
}
MPi->Width = x;
MPi->Height = y;
FreeVec(r);
FreeVec(g);
FreeVec(b);
FreeVec(t);
CloseProgressWindow();
CloseDownScreen();
return TRUE;
}
else { // E_AllocBitMap
msg = GetMg(MSG_ERR_ALLOCE);
}
}
else { // AllocVec red,green,blue
msg = GetMg(MSG_ERR_NOMEM);
}
if (r) FreeVec(r);
if (g) FreeVec(g);
if (b) FreeVec(b);
if (t) FreeVec(t);
}
else { // AllocVec red,green,blue
msg = GetMg(MSG_ERR_NOMEM);
}
if (red) FreeVec(red);
if (green) FreeVec(green);
if (blue) FreeVec(blue);
CloseLibrary(EGSBase);
}
else {
// RGB || Grey
if (MPi->GreyScale) {
UBYTE *red,*t;
if ((red = AllocVec((int)x*y,0)) &&
(t = AllocVec((int)x*y,0))) {
AddMessageNo(MSG_SCALEG);
RescaleXY(MPi->Red,MPi->Width,MPi->Height,red,x,y,t);
FreeVec(MPi->Red);
FreeVec(t);
MPi->Width = x;
MPi->Height = y;
MPi->Red = red;
MPi->Green = red;
MPi->Blue = red;
CloseProgressWindow();
CloseDownScreen();
return TRUE;
}
else { // AllocVec red,green,blue
msg = GetMg(MSG_ERR_NOMEM);
if (red) {
FreeVec(red);
}
}
}
else {
UBYTE *red,*green=NULL,*blue=NULL,*t,*t1,*t2;
if ((red = AllocVec((int)x*y,0)) &&
(green = AllocVec((int)x*y,0)) &&
(blue = AllocVec((int)x*y,0)) &&
(t = AllocVec((int)x*y,0))) {
AddMessageNo(MSG_SCALER);
if ((t1 = AllocVec((int)x*y,0)) &&
(t2 = AllocVec((int)x*y,0))) {
RescaleXYRGB(MPi->Red,MPi->Green,MPi->Blue,MPi->Width,MPi->Height,red,green,blue,x,y,t,t1,t2);
FreeVec(t1);
FreeVec(t2);
}
else {
if (t1) {
FreeVec(t1);
}
RescaleXY(MPi->Red,MPi->Width,MPi->Height,red,x,y,t);
RescaleXY(MPi->Green,MPi->Width,MPi->Height,green,x,y,t);
RescaleXY(MPi->Blue,MPi->Width,MPi->Height,blue,x,y,t);
}
FreeVec(MPi->Red);
FreeVec(MPi->Green);
FreeVec(MPi->Blue);
FreeVec(t);
MPi->Width = x;
MPi->Height = y;
MPi->Red = red;
MPi->Green = green;
MPi->Blue = blue;
CloseProgressWindow();
CloseDownScreen();
return TRUE;
}
else { // AllocVec red,green,blue
msg = GetMg(MSG_ERR_NOMEM);
}
if (red) FreeVec(red);
if (green) FreeVec(green);
if (blue) FreeVec(blue);
}
}
}
strcpy(ErrorMessage,msg);
CloseProgressWindow();
CloseDownScreen();
return FALSE;
}
/****** MPImage.library/MPScaleGrey ***************************************
*
* NAME
* MPScaleGrey -- Scales a GreyScale image (V7)
*
* SYNOPSIS
* MPScaleGrey( Old,New,OWidth,OHeight,NWidth,NHeight,Temp)
* A0 A1 D0 D1 D2 D3 A2
*
* void MPScaleGrey
* ( UBYTE *,UBYTE *,UWORD,UWORD,UWORD,UWORD,UBYTE *);
*
* FUNCTION
* Scales an RGB image.
*
* INPUTS
* Old - Contains existing chunky pixels.
* New - Buffer for the new chunky pixels.
* OWidth - Current Width.
* OHeight - Current Height.
* NWidth - New Width.
* NHeight - New Height.
* Temp - Temporary buffer sized for the new image.
*
* RESULT
* The data pointed to by New is updated to the scaled image.
*
* EXAMPLE
*
* NOTES
*
* BUGS
* Not tested.
*
* SEE ALSO
* MPScaleRGB().
*
*****************************************************************************
*
*/
void __asm __saveds
MPScaleGrey(register __a0 UBYTE *Old,register __a1 UBYTE *New,
register __d0 UWORD OWidth,register __d1 UWORD OHeight,
register __d2 UWORD NWidth,register __d3 UWORD NHeight,
register __a2 UBYTE *Temp) {
RescaleXY(Old,OWidth,OHeight,
New,NWidth,NHeight,Temp);
}
/* in = chunky in
* w = old width
* h = old height
* out= chunky out
* x = new width
* y = new height
* t = Temp buffer
*/
static void
RescaleXY(UBYTE *in,UWORD w,UWORD h,UBYTE *out,UWORD x,UWORD y,UBYTE *t) {
float xfact,yfact;
xfact = ((float)w)/x;
yfact = ((float)h)/y;
if (x == w) {
if (y == h) {
AddMessageNo(MSG_COPY);
memcpy(out,in,w*h);
return;
}
if (y < h) {
// x == w, y < h
UWORD j;
UBYTE *op = out;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
AddMessageNo(MSG_SLTY);
SetMax(y);
for (j=0; j<y; j++) {
UWORD i;
UBYTE *tin;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
if (ys > 0) {
tin = in + ((ys-1) * w);
}
else {
tin = in + (ys * w);
}
for (i=0; i<x; i++) {
float newf=0.0;
UWORD l;
UBYTE *tint = tin;
if (ys > 0) {
newf += tint[i] * tf;
tint += w;
}
for (l = ys; l < ye; l++) {
newf += tint[i];
tint += w;
}
if (ye < h) {
newf += tint[i] * bf;
}
*op++ = newf/yfact;
}
ys = ye + 1;
tf = ys - yf;
}
return;
}
{
// x == w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *op = t;
UBYTE *tin;
UWORD i;
AddMessageNo(MSG_SGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
tin = in + (ys * w);
if (ys == ye) {
for (i=0; i<x; i++) {
*op++ = *tin++;
}
}
else {
float tf,bf;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=0; i<x; i++) {
*op++ = ((*tin * tf) + (tin[w] * bf)) / yfact;
tin++;
}
ys = ye;
}
}
tin = in + ((h-1) * w);
for (i=0; i<x; i++) {
*op++ = *tin++;
}
SmoothY(t,out,h,x,y);
return;
}
}
// x != w
if (x < w) {
// x < w
if (y == h) {
// x < w, y == h
UWORD j;
UBYTE *op = out;
UBYTE *tin = in;
AddMessageNo(MSG_SLTX);
SetMax(y);
for (j=0; j<y; j++) {
float xf = 0.0;
float lf=0.0,rf;
UWORD xs=0,xe;
UWORD i;
SetCur(j);
for (i=0; i<x; i++) {
float newf=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newf += tin[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newf += tin[k];
}
if (xe < w) {
newf += tin[xe] * rf;
}
*op++ = newf/xfact;
xs = xe + 1;
lf = xs - xf;
}
tin += w;
}
return;
}
if (y < h) {
// x < w, y < h
UWORD j;
float divf;
UBYTE *op = out;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
divf = xfact * yfact;
AddMessageNo(MSG_SLTXLTY);
SetMax(y);
for (j=0; j<y; j++) {
float xf = 0.0;
float lf=0.0,rf;
UWORD xs=0,xe;
UWORD i;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
for (i=0; i<x; i++) {
float newf=0.0;
UBYTE *tin;
UWORD l;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (ys > 0) {
UWORD k;
tin = in + ((ys-1) * w);
if (xs > 0) {
newf += tin[xs-1] * lf * tf;
}
for (k = xs; k < xe; k++) {
newf += tin[k] * tf;
}
if (xe < w) {
newf += tin[xe] * rf * tf;
}
tin += w;
}
else {
tin = in + (ys * w);
}
for (l = ys; l < ye; l++) {
UWORD k;
if (xs > 0) {
newf += tin[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newf += tin[k];
}
if (xe < w) {
newf += tin[xe] * rf;
}
tin += w;
}
if (ye < h) {
UWORD k;
newf += tin[xs-1] * lf * bf;
for (k = xs; k < xe; k++) {
newf += tin[k] * bf;
}
if (xe < w) {
newf += tin[xe] * rf * bf;
}
}
*op++ = newf/divf;
xs = xe + 1;
lf = xs - xf;
}
ys = ye + 1;
tf = ys - yf;
}
return;
}
{
// x < w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *op = t;
UBYTE *tin;
UWORD i;
float divf = xfact * yfact;
UWORD xs,xe;
float xf;
float lf,rf;
AddMessageNo(MSG_SLTXGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
xf = 0.0;
lf = 0.0;
xs = 0;
yf += yfact;
ye = (UWORD)yf;
tin = in + (ys * w);
if (ys == ye) {
for (i=0; i<x; i++) {
float newf=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newf += tin[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newf += tin[k];
}
if (xe < w) {
newf += tin[xe] * rf;
}
*op++ = newf/xfact;
xs = xe + 1;
lf = xs - xf;
}
}
else {
float tf,bf;
UWORD k;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=0; i<x; i++) {
float newf=0.0;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newf += ((tin[xs-1] * tf) + (tin[xs-1+w] * bf)) * lf;
}
for (k = xs; k < xe; k++) {
newf += (tin[k] * tf) + (tin[k+w] * bf);
}
if (xe < w) {
newf += ((tin[xe] * tf) + (tin[xe+w] * bf)) * rf;
}
*op++ = newf/divf;
xs = xe + 1;
lf = xs - xf;
}
ys = ye;
}
}
tin = in + ((h-1) * w);
xs = 0;
lf = 0.0;
xf = 0.0;
for (i=0; i<x; i++) {
float newf=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newf += tin[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newf += tin[k];
}
if (xe < w) {
newf += tin[xe] * rf;
}
*op++ = newf/xfact;
xs = xe + 1;
lf = xs - xf;
}
SmoothY(t,out,h,x,y);
return;
}
}
// x > w
if (y == h) {
// x > w, y == h
UWORD j;
UBYTE *op = t;
UBYTE *tin = in;
UWORD i;
UBYTE *tint;
AddMessageNo(MSG_SGTX);
SetMax(y);
for (j=0; j<y; j++) {
UWORD xs=0,xe;
float xf=0.0;
SetCur(j);
tint = tin;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*op++ = *tint;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*op++ = ((*tint * lf) + (tint[1] * rf)) / xfact;
tint++;
xs = xe;
}
}
*op++ = *tint;
tin += w;
}
SmoothX(t,out,w,x,y);
return;
}
if (y > h) {
// x > w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *op = t;
UBYTE *tin;
UWORD i;
float divf = xfact * yfact;
UWORD xs,xe;
float xf;
AddMessageNo(MSG_SGTXGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
xs=0;
xf=0.0;
yf += yfact;
ye = (UWORD)yf;
tin = in + (ys * w);
if (ys == ye) {
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*op++ = *tin;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*op++ = ((*tin * lf) + (tin[1] * rf)) / xfact;
tin++;
xs = xe;
}
}
*op++ = *tin;
}
else {
float tf,bf;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*op++ = ((*tin * tf) + (tin[w] * bf)) / yfact;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*op++ = ((*tin * lf * tf) + (tin[1] * rf * tf) +
(tin[w] * lf * bf) + (tin[w+1] * rf * bf)) / divf;
tin++;
xs = xe;
}
}
*op++ = *tin;
ys = ye;
}
}
tin = in + ((h-1) * w);
xf = 0.0;
xs = 0;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*op++ = *tin;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*op++ = ((*tin * lf) + (tin[1] * rf)) / xfact;
tin++;
xs = xe;
}
}
*op = *tin;
SmoothXY(t,out,w,h,x,y);
return;
}
{
// x > w, y < h
UWORD j;
UBYTE *op = t;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
UBYTE *tin;
float divf = xfact * yfact;
AddMessageNo(MSG_SGTXLTY);
SetMax(y);
for (j=0; j<y; j++) {
UWORD i;
UBYTE *tint;
float newf;
UWORD l;
UWORD xs=0,xe;
float xf=0.0;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
if (ys > 0) {
tin = in + ((ys-1) * w);
}
else {
tin = in + (ys * w);
}
for (i=1; i<x; i++) {
newf=0.0;
xf += xfact;
xe = (UWORD)xf;
tint = tin;
if (xs == xe) {
if (ys > 0) {
newf += tint[xs] * tf;
tint += w;
}
for (l = ys; l < ye; l++) {
newf += tint[xs];
tint += w;
}
if (ye < h) {
newf += tint[xs] * bf;
}
*op++ = newf/yfact;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
if (ys > 0) {
newf += ((tint[xs] * lf) + (tint[xe] * rf)) * tf;
tint += w;
}
for (l = ys; l < ye; l++) {
newf += ((tint[xs] * lf) + (tint[xe] * rf));
tint += w;
}
if (ye < h) {
newf += ((tint[xs] * lf) + (tint[xe] * rf)) * bf;
}
*op++ = newf/divf;
xs = xe;
}
}
tint = tin;
newf = 0.0;
if (ys > 0) {
newf += tint[w-1] * tf;
tint += w;
}
for (l = ys; l < ye; l++) {
newf += tint[w-1];
tint += w;
}
if (ye < h) {
newf += tint[w-1] * bf;
}
*op++ = newf/yfact;
ys = ye + 1;
tf = ys - yf;
}
SmoothX(t,out,w,x,y);
return;
}
}
static void
SmoothX(UBYTE *in,UBYTE *out,UWORD w,UWORD x,UWORD y) {
int t;
int i,j;
UBYTE *p,*o;
AddMessageNo(MSG_SMX);
t = x/w;
if (t < 2) { // less than 2 times size
AddMessageNo(MSG_COPY);
memcpy(out,in,x*y);
return;
}
if (t < 3) { // less than 3 times the size
p = in;
o = out;
AddMessageNo(MSG_LT3);
SetMax(y);
for (j = 0; j < y; ++j) {
SetCur(j);
for (i = 1; i < x; ++i) { // Skip first column
*o++ = (*p + p[1])>>1;
++p;
}
*o++ = *p++;
}
return;
} // >= 3 times size
p = in;
o = out;
AddMessageNo(MSG_GE3);
SetMax(y);
for (j = 0; j < y; ++j) {
SetCur(j);
*o++ = *p;
for (i = 2; i < x; ++i) { // Skip first and last columns
*o++ = (*p + p[1] + p[2])/3;
++p;
}
++p;
*o++ = *p++;
}
}
static void
SmoothY(UBYTE *in,UBYTE *out,UWORD h,UWORD x,UWORD y) {
int t;
int i,j;
UBYTE *p,*p1,*p2,*o;
AddMessageNo(MSG_SMY);
t = y/h;
if (t < 2) {
AddMessageNo(MSG_COPY);
memcpy(out,in,x*y);
return;
}
if (t < 3) {
p = in;
p1 = in;
o = out;
for (i = 0; i < x; ++i) {
*o++ = *p++;
}
AddMessageNo(MSG_LT3);
SetMax(y);
for (j = 1; j < y; ++j) { // Skip first row
SetCur(j);
for (i = 0; i < x; ++i) {
*o++ = (*p++ + *p1++)>>1;
}
}
return;
}
p1 = in;
p = in;
p2 = in + x + x;
o = out;
for (i = 0; i < x; ++i) {
*o++ = *p++;
}
AddMessageNo(MSG_GE3);
SetMax(y);
for (j = 2; j < y; ++j) { // Skip first and last rows
SetCur(j);
for (i = 0; i < x; ++i) {
*o++ = (*p++ + *p1++ + *p2++)/3;
}
}
for (i = 0; i < x; ++i) {
*o++ = *p++;
}
}
static void
SmoothXY(UBYTE *in,UBYTE *out,UWORD w,UWORD h,UWORD x,UWORD y) {
int tx,ty;
int i,j;
UBYTE *p,*p1,*p2,*o;
AddMessageNo(MSG_SMXY);
tx = x/w;
ty = y/h;
if ((tx < 2) && (ty < 2)) {
AddMessageNo(MSG_COPY);
memcpy(out,in,x*y);
return;
}
if (ty < 2) { // No y smooth required
SmoothX(in,out,w,x,y);
return;
}
if (tx < 2) { // No x smooth required
SmoothY(in,out,h,x,y);
return;
}
if (tx < 3) {
if (ty < 3) {
p = in;
p1 = in;
o = out;
*o++ = *p;
for (i = 1; i < x; ++i) {
*o++ = (*p + p[1])>>1;
++p;
}
++p;
AddMessageNo(MSG_XLT3YLT3);
SetMax(y);
for (j = 1; j < y; ++j) {
SetCur(j);
*o++ = (*p + *p1)>>1;
for (i = 1; i < x; ++i) {
*o++ = (*p + p[1] + *p1 + p1[1])>>2;
++p;
++p1;
}
++p;
++p1;
}
return;
} // tx < 3 ty >=3
p1 = in;
p = in;
p2 = in + x + x;
o = out;
*o++ = *p;
for (i = 1; i < x; ++i) {
*o++ = (*p + p[1])>>1;
++p;
}
++p;
AddMessageNo(MSG_XLT3YGE3);
SetMax(y);
for (j = 2; j < y; ++j) {
SetCur(j);
*o++ = (*p + *p1 + *p2)/3;
for (i = 1; i < x; ++i) {
*o++ = (*p + p[1] + *p1 + p1[1] + *p2 + p2[1])/6;
++p;
++p1;
++p2;
}
++p;
++p1;
++p2;
}
*o++ = *p;
for (i = 1; i < x; ++i) {
*o++ = (*p + p[1])>>1;
++p;
}
return;
} // tx >= 3
if (ty < 3) {
p1 = in;
p = in;
o = out;
*o++ = *p;
for (i = 2; i < x; ++i) { // Skip first and last columns
*o++ = (*p + p[1] + p[2])/3;
++p;
}
++p;
*o++ = *p++;
AddMessageNo(MSG_XGE3YLT3);
SetMax(y);
for (j = 1; j < y; ++j) {
SetCur(j);
*o++ = (*p + *p1)>>1;
for (i = 2; i < x; ++i) {
*o++ = (*p + p[1] + p[2] + *p1 + p1[1] + p1[2])/6;
++p;
++p1;
}
++p1;
++p;
*o++ = (*p++ + *p1++)>>1;
}
return;
} // tx >= 3, ty >= 3
p1 = in;
p = in;
p2 = in + x + x;
o = out;
*o++ = *p;
for (i = 2; i < x; ++i) { // Skip first and last columns
*o++ = (*p + p[1] + p[2])/3;
++p;
}
++p;
*o++ = *p++;
AddMessageNo(MSG_XGE3YGE3);
SetMax(y);
for (j = 2; j < y; ++j) {
SetCur(j);
*o++ = (*p + *p1 + *p2)/3;
for (i = 2; i < x; ++i) {
*o++ = (*p + p[1] + p[2] + *p1 + p1[1] + p1[2] + *p2 + p2[1] + p2[2])/9;
++p;
++p1;
++p2;
}
++p1;
++p;
++p2;
*o++ = (*p++ + *p1++ + *p2++)/3;
}
*o++ = *p;
for (i = 2; i < x; ++i) { // Skip first and last columns
*o++ = (*p + p[1] + p[2])/3;
++p;
}
*o = *p;
}
/****** MPImage.library/MPScaleRGB ***************************************
*
* NAME
* MPScaleRGB -- Scales an RGB image (V7)
*
* SYNOPSIS
* MPScaleRGB( Old,New,Temp)
* A0 A1 A2
*
* void MPScaleRGB
* ( struct MPProcess *,struct MPProcess *,struct MPProcess *);
*
* FUNCTION
* Scales an RGB image.
*
* INPUTS
* Old - Contains the Red,Green and Blue chunky pixels
* and the Width and Height of the current image.
* New - Contains the Red,Green and Blue chunky pixels
* and the Width and Height for the new image.
* Temp - Contains 3 temporary buffers sized for the new image.
*
* RESULT
* The data pointed to by New->Red/Green/Blue is updated to
* the scaled image.
*
* EXAMPLE
*
* NOTES
*
* BUGS
* Not tested.
*
* SEE ALSO
* MPScaleGrey().
*
*****************************************************************************
*
*/
void __asm __saveds
MPScaleRGB(register __a0 struct MPProcess *Old,register __a1 struct MPProcess *New,
register __a2 struct MPProcess *Temp) {
RescaleXYRGB(Old->Red,Old->Green,Old->Blue,Old->Width,Old->Height,
New->Red,New->Green,New->Blue,New->Width,New->Height,
Temp->Red,Temp->Green,Temp->Blue);
}
/* inr = chunky in r
* ing = chunky in g
* inb = chunky in b
* w = old width
* h = old height
* outr= chunky out r
* outg= chunky out g
* outb= chunky out b
* x = new width
* y = new height
* tr = Temp buffer r
* tg = Temp buffer g
* tb = Temp buffer b
*/
static
void
RescaleXYRGB(UBYTE *inr,UBYTE *ing,UBYTE *inb,UWORD w,UWORD h,UBYTE *outr,UBYTE *outg,UBYTE *outb,
UWORD x,UWORD y,UBYTE *tr,UBYTE *tg,UBYTE *tb) {
float xfact,yfact;
xfact = ((float)w)/x;
yfact = ((float)h)/y;
if (x == w) {
if (y == h) {
AddMessageNo(MSG_COPY);
memcpy(outr,inr,w*h);
memcpy(outg,ing,w*h);
memcpy(outb,inb,w*h);
return;
}
if (y < h) {
// x == w, y < h
UWORD j;
UBYTE *opr = outr;
UBYTE *opg = outg;
UBYTE *opb = outb;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
AddMessageNo(MSG_SLTY);
SetMax(y);
for (j=0; j<y; j++) {
UWORD i;
UBYTE *tinr;
UBYTE *ting;
UBYTE *tinb;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
if (ys > 0) {
tinr = inr + ((ys-1) * w);
ting = ing + ((ys-1) * w);
tinb = inb + ((ys-1) * w);
}
else {
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
}
for (i=0; i<x; i++) {
float newfr=0.0;
float newfg=0.0;
float newfb=0.0;
UWORD l;
UBYTE *tintr = tinr;
UBYTE *tintg = ting;
UBYTE *tintb = tinb;
if (ys > 0) {
newfr += tintr[i] * tf;
tintr += w;
newfg += tintg[i] * tf;
tintg += w;
newfb += tintb[i] * tf;
tintb += w;
}
for (l = ys; l < ye; l++) {
newfr += tintr[i];
tintr += w;
newfg += tintg[i];
tintg += w;
newfb += tintb[i];
tintb += w;
}
if (ye < h) {
newfr += tintr[i] * bf;
newfg += tintg[i] * bf;
newfb += tintb[i] * bf;
}
*opr++ = newfr/yfact;
*opg++ = newfg/yfact;
*opb++ = newfb/yfact;
}
ys = ye + 1;
tf = ys - yf;
}
return;
}
{
// x == w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *opr = tr;
UBYTE *tinr;
UBYTE *opg = tg;
UBYTE *ting;
UBYTE *opb = tb;
UBYTE *tinb;
UWORD i;
AddMessageNo(MSG_SGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
if (ys == ye) {
for (i=0; i<x; i++) {
*opr++ = *tinr++;
*opg++ = *ting++;
*opb++ = *tinb++;
}
}
else {
float tf,bf;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=0; i<x; i++) {
*opr++ = ((*tinr * tf) + (tinr[w] * bf)) / yfact;
tinr++;
*opg++ = ((*ting * tf) + (ting[w] * bf)) / yfact;
ting++;
*opb++ = ((*tinb * tf) + (tinb[w] * bf)) / yfact;
tinb++;
}
ys = ye;
}
}
tinr = inr + ((h-1) * w);
ting = ing + ((h-1) * w);
tinb = inb + ((h-1) * w);
for (i=0; i<x; i++) {
*opr++ = *tinr++;
*opg++ = *ting++;
*opb++ = *tinb++;
}
SmoothY(tr,outr,h,x,y);
SmoothY(tg,outg,h,x,y);
SmoothY(tb,outb,h,x,y);
return;
}
}
// x != w
if (x < w) {
// x < w
if (y == h) {
// x < w, y == h
UWORD j;
UBYTE *opr = outr;
UBYTE *tinr = inr;
UBYTE *opg = outg;
UBYTE *ting = ing;
UBYTE *opb = outb;
UBYTE *tinb = inb;
AddMessageNo(MSG_SLTX);
SetMax(y);
for (j=0; j<y; j++) {
float xf = 0.0;
float lf=0.0,rf;
UWORD xs=0,xe;
UWORD i;
SetCur(j);
for (i=0; i<x; i++) {
float newfr=0.0;
float newfg=0.0;
float newfb=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newfr += tinr[xs-1] * lf;
newfg += ting[xs-1] * lf;
newfb += tinb[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newfr += tinr[k];
newfg += ting[k];
newfb += tinb[k];
}
if (xe < w) {
newfr += tinr[xe] * rf;
newfg += ting[xe] * rf;
newfb += tinb[xe] * rf;
}
*opr++ = newfr/xfact;
*opg++ = newfg/xfact;
*opb++ = newfb/xfact;
xs = xe + 1;
lf = xs - xf;
}
tinr += w;
ting += w;
tinb += w;
}
return;
}
if (y < h) {
// x < w, y < h
UWORD j;
float divf;
UBYTE *opr = outr;
UBYTE *opg = outg;
UBYTE *opb = outb;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
divf = xfact * yfact;
AddMessageNo(MSG_SLTXLTY);
SetMax(y);
for (j=0; j<y; j++) {
float xf = 0.0;
float lf=0.0,rf;
UWORD xs=0,xe;
UWORD i;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
for (i=0; i<x; i++) {
float newfr=0.0;
UBYTE *tinr;
float newfg=0.0;
UBYTE *ting;
float newfb=0.0;
UBYTE *tinb;
UWORD l;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (ys > 0) {
UWORD k;
tinr = inr + ((ys-1) * w);
ting = ing + ((ys-1) * w);
tinb = inb + ((ys-1) * w);
if (xs > 0) {
newfr += tinr[xs-1] * lf * tf;
newfg += ting[xs-1] * lf * tf;
newfb += tinb[xs-1] * lf * tf;
}
for (k = xs; k < xe; k++) {
newfr += tinr[k] * tf;
newfg += ting[k] * tf;
newfb += tinb[k] * tf;
}
if (xe < w) {
newfr += tinr[xe] * rf * tf;
newfg += ting[xe] * rf * tf;
newfb += tinb[xe] * rf * tf;
}
tinr += w;
ting += w;
tinb += w;
}
else {
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
}
for (l = ys; l < ye; l++) {
UWORD k;
if (xs > 0) {
newfr += tinr[xs-1] * lf;
newfg += ting[xs-1] * lf;
newfb += tinb[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newfr += tinr[k];
newfg += ting[k];
newfb += tinb[k];
}
if (xe < w) {
newfr += tinr[xe] * rf;
newfg += ting[xe] * rf;
newfb += tinb[xe] * rf;
}
tinr += w;
ting += w;
tinb += w;
}
if (ye < h) {
UWORD k;
newfr += tinr[xs-1] * lf * bf;
newfg += ting[xs-1] * lf * bf;
newfb += tinb[xs-1] * lf * bf;
for (k = xs; k < xe; k++) {
newfr += tinr[k] * bf;
newfg += ting[k] * bf;
newfb += tinb[k] * bf;
}
if (xe < w) {
newfr += tinr[xe] * rf * bf;
newfg += ting[xe] * rf * bf;
newfb += tinb[xe] * rf * bf;
}
}
*opr++ = newfr/divf;
*opg++ = newfg/divf;
*opb++ = newfb/divf;
xs = xe + 1;
lf = xs - xf;
}
ys = ye + 1;
tf = ys - yf;
}
return;
}
{
// x < w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *opr = tr;
UBYTE *tinr;
UBYTE *opg = tg;
UBYTE *ting;
UBYTE *opb = tb;
UBYTE *tinb;
UWORD i;
float divf = xfact * yfact;
UWORD xs,xe;
float xf;
float lf,rf;
AddMessageNo(MSG_SLTXGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
xf = 0.0;
lf = 0.0;
xs = 0;
yf += yfact;
ye = (UWORD)yf;
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
if (ys == ye) {
for (i=0; i<x; i++) {
float newfr=0.0;
float newfg=0.0;
float newfb=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newfr += tinr[xs-1] * lf;
newfg += ting[xs-1] * lf;
newfb += tinb[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newfr += tinr[k];
newfg += ting[k];
newfb += tinb[k];
}
if (xe < w) {
newfr += tinr[xe] * rf;
newfg += ting[xe] * rf;
newfb += tinb[xe] * rf;
}
*opr++ = newfr/xfact;
*opg++ = newfg/xfact;
*opb++ = newfb/xfact;
xs = xe + 1;
lf = xs - xf;
}
}
else {
float tf,bf;
UWORD k;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=0; i<x; i++) {
float newfr=0.0;
float newfg=0.0;
float newfb=0.0;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newfr += ((tinr[xs-1] * tf) + (tinr[xs-1+w] * bf)) * lf;
newfg += ((ting[xs-1] * tf) + (ting[xs-1+w] * bf)) * lf;
newfb += ((tinb[xs-1] * tf) + (tinb[xs-1+w] * bf)) * lf;
}
for (k = xs; k < xe; k++) {
newfr += (tinr[k] * tf) + (tinr[k+w] * bf);
newfg += (ting[k] * tf) + (ting[k+w] * bf);
newfb += (tinb[k] * tf) + (tinb[k+w] * bf);
}
if (xe < w) {
newfr += ((tinr[xe] * tf) + (tinr[xe+w] * bf)) * rf;
newfg += ((ting[xe] * tf) + (ting[xe+w] * bf)) * rf;
newfb += ((tinb[xe] * tf) + (tinb[xe+w] * bf)) * rf;
}
*opr++ = newfr/divf;
*opg++ = newfg/divf;
*opb++ = newfb/divf;
xs = xe + 1;
lf = xs - xf;
}
ys = ye;
}
}
tinr = inr + ((h-1) * w);
ting = ing + ((h-1) * w);
tinb = inb + ((h-1) * w);
xs = 0;
lf = 0.0;
xf = 0.0;
for (i=0; i<x; i++) {
float newfr=0.0;
float newfg=0.0;
float newfb=0.0;
UWORD k;
xf += xfact;
xe = (UWORD)xf;
rf = xf - xe;
if (xs > 0) {
newfr += tinr[xs-1] * lf;
newfg += ting[xs-1] * lf;
newfb += tinb[xs-1] * lf;
}
for (k = xs; k < xe; k++) {
newfr += tinr[k];
newfg += ting[k];
newfb += tinb[k];
}
if (xe < w) {
newfr += tinr[xe] * rf;
newfg += ting[xe] * rf;
newfb += tinb[xe] * rf;
}
*opr++ = newfr/xfact;
*opg++ = newfg/xfact;
*opb++ = newfb/xfact;
xs = xe + 1;
lf = xs - xf;
}
SmoothY(tr,outr,h,x,y);
SmoothY(tg,outg,h,x,y);
SmoothY(tb,outb,h,x,y);
return;
}
}
// x > w
if (y == h) {
// x > w, y == h
UWORD j;
UBYTE *opr = tr;
UBYTE *tinr = inr;
UBYTE *opg = tg;
UBYTE *ting = ing;
UBYTE *opb = tb;
UBYTE *tinb = inb;
UWORD i;
UBYTE *tintr;
UBYTE *tintg;
UBYTE *tintb;
AddMessageNo(MSG_SGTX);
SetMax(y);
for (j=0; j<y; j++) {
UWORD xs=0,xe;
float xf=0.0;
SetCur(j);
tintr = tinr;
tintg = ting;
tintb = tinb;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*opr++ = *tintr;
*opg++ = *tintg;
*opb++ = *tintb;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*opr++ = ((*tintr * lf) + (tintr[1] * rf)) / xfact;
*opg++ = ((*tintg * lf) + (tintg[1] * rf)) / xfact;
*opb++ = ((*tintb * lf) + (tintb[1] * rf)) / xfact;
tintr++;
tintg++;
tintb++;
xs = xe;
}
}
*opr++ = *tintr;
tinr += w;
*opg++ = *tintg;
ting += w;
*opb++ = *tintb;
tinb += w;
}
SmoothX(tr,outr,w,x,y);
SmoothX(tg,outg,w,x,y);
SmoothX(tb,outb,w,x,y);
return;
}
if (y > h) {
// x > w, y > h
UWORD j;
UWORD ys=0,ye;
float yf=0.0;
UBYTE *opr = tr;
UBYTE *tinr;
UBYTE *opg = tg;
UBYTE *ting;
UBYTE *opb = tb;
UBYTE *tinb;
UWORD i;
float divf = xfact * yfact;
UWORD xs,xe;
float xf;
AddMessageNo(MSG_SGTXGTY);
SetMax(y);
for (j=1; j<y; j++) {
SetCur(j);
xs=0;
xf=0.0;
yf += yfact;
ye = (UWORD)yf;
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
if (ys == ye) {
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*opr++ = *tinr;
*opg++ = *ting;
*opb++ = *tinb;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*opr++ = ((*tinr * lf) + (tinr[1] * rf)) / xfact;
tinr++;
*opg++ = ((*ting * lf) + (ting[1] * rf)) / xfact;
ting++;
*opb++ = ((*tinb * lf) + (tinb[1] * rf)) / xfact;
tinb++;
xs = xe;
}
}
*opr++ = *tinr;
*opg++ = *ting;
*opb++ = *tinb;
}
else {
float tf,bf;
bf = yf - floor(yf);
tf = yfact - bf;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*opr++ = ((*tinr * tf) + (tinr[w] * bf)) / yfact;
*opg++ = ((*ting * tf) + (ting[w] * bf)) / yfact;
*opb++ = ((*tinb * tf) + (tinb[w] * bf)) / yfact;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*opr++ = ((*tinr * lf * tf) + (tinr[1] * rf * tf) +
(tinr[w] * lf * bf) + (tinr[w+1] * rf * bf)) / divf;
tinr++;
*opg++ = ((*ting * lf * tf) + (ting[1] * rf * tf) +
(ting[w] * lf * bf) + (ting[w+1] * rf * bf)) / divf;
ting++;
*opb++ = ((*tinb * lf * tf) + (tinb[1] * rf * tf) +
(tinb[w] * lf * bf) + (tinb[w+1] * rf * bf)) / divf;
tinb++;
xs = xe;
}
}
*opr++ = *tinr;
*opg++ = *ting;
*opb++ = *tinb;
ys = ye;
}
}
tinr = inr + ((h-1) * w);
ting = ing + ((h-1) * w);
tinb = inb + ((h-1) * w);
xf = 0.0;
xs = 0;
for (i=1; i<x; i++) {
xf += xfact;
xe = (UWORD)xf;
if (xs == xe) {
*opr++ = *tinr;
*opg++ = *ting;
*opb++ = *tinb;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
*opr++ = ((*tinr * lf) + (tinr[1] * rf)) / xfact;
tinr++;
*opg++ = ((*ting * lf) + (ting[1] * rf)) / xfact;
ting++;
*opb++ = ((*tinb * lf) + (tinb[1] * rf)) / xfact;
tinb++;
xs = xe;
}
}
*opr = *tinr;
*opg = *ting;
*opb = *tinb;
SmoothXY(tr,outr,w,h,x,y);
SmoothXY(tg,outg,w,h,x,y);
SmoothXY(tb,outb,w,h,x,y);
return;
}
{
// x > w, y < h
UWORD j;
UBYTE *opr = tr;
UBYTE *opg = tg;
UBYTE *opb = tb;
float tf=0.0, bf;
float yf = 0.0;
UWORD ys=0,ye;
UBYTE *tinr;
UBYTE *ting;
UBYTE *tinb;
float divf = xfact * yfact;
AddMessageNo(MSG_SGTXLTY);
SetMax(y);
for (j=0; j<y; j++) {
UWORD i;
UBYTE *tintr;
float newfr;
UBYTE *tintg;
float newfg;
UBYTE *tintb;
float newfb;
UWORD l;
UWORD xs=0,xe;
float xf=0.0;
SetCur(j);
yf += yfact;
ye = (UWORD)yf;
bf = yf - ye;
if (ys > 0) {
tinr = inr + ((ys-1) * w);
ting = ing + ((ys-1) * w);
tinb = inb + ((ys-1) * w);
}
else {
tinr = inr + (ys * w);
ting = ing + (ys * w);
tinb = inb + (ys * w);
}
for (i=1; i<x; i++) {
newfr=0.0;
newfg=0.0;
newfb=0.0;
xf += xfact;
xe = (UWORD)xf;
tintr = tinr;
tintg = ting;
tintb = tinb;
if (xs == xe) {
if (ys > 0) {
newfr += tintr[xs] * tf;
tintr += w;
newfg += tintg[xs] * tf;
tintg += w;
newfb += tintb[xs] * tf;
tintb += w;
}
for (l = ys; l < ye; l++) {
newfr += tintr[xs];
tintr += w;
newfg += tintg[xs];
tintg += w;
newfb += tintb[xs];
tintb += w;
}
if (ye < h) {
newfr += tintr[xs] * bf;
newfg += tintg[xs] * bf;
newfb += tintb[xs] * bf;
}
*opr++ = newfr/yfact;
*opg++ = newfg/yfact;
*opb++ = newfb/yfact;
}
else {
float lf,rf;
rf = xf - floor(xf);
lf = xfact - rf;
if (ys > 0) {
newfr += ((tintr[xs] * lf) + (tintr[xe] * rf)) * tf;
tintr += w;
newfg += ((tintg[xs] * lf) + (tintg[xe] * rf)) * tf;
tintg += w;
newfb += ((tintb[xs] * lf) + (tintb[xe] * rf)) * tf;
tintb += w;
}
for (l = ys; l < ye; l++) {
newfr += ((tintr[xs] * lf) + (tintr[xe] * rf));
tintr += w;
newfg += ((tintg[xs] * lf) + (tintg[xe] * rf));
tintg += w;
newfb += ((tintb[xs] * lf) + (tintb[xe] * rf));
tintb += w;
}
if (ye < h) {
newfr += ((tintr[xs] * lf) + (tintr[xe] * rf)) * bf;
newfg += ((tintg[xs] * lf) + (tintg[xe] * rf)) * bf;
newfb += ((tintb[xs] * lf) + (tintb[xe] * rf)) * bf;
}
*opr++ = newfr/divf;
*opg++ = newfg/divf;
*opb++ = newfb/divf;
xs = xe;
}
}
tintr = tinr;
newfr = 0.0;
tintg = ting;
newfg = 0.0;
tintb = tinb;
newfb = 0.0;
if (ys > 0) {
newfr += tintr[w-1] * tf;
tintr += w;
newfg += tintg[w-1] * tf;
tintg += w;
newfb += tintb[w-1] * tf;
tintb += w;
}
for (l = ys; l < ye; l++) {
newfr += tintr[w-1];
tintr += w;
newfg += tintg[w-1];
tintg += w;
newfb += tintb[w-1];
tintb += w;
}
if (ye < h) {
newfr += tintr[w-1] * bf;
newfg += tintg[w-1] * bf;
newfb += tintb[w-1] * bf;
}
*opr++ = newfr/yfact;
*opg++ = newfg/yfact;
*opb++ = newfb/yfact;
ys = ye + 1;
tf = ys - yf;
}
SmoothX(tr,outr,w,x,y);
SmoothX(tg,outg,w,x,y);
SmoothX(tb,outb,w,x,y);
return;
}
}